﻿#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using HouseHoldBudget.Core.Entities.User;
using HouseHoldBudget.Framework;
using HouseHoldBudget.Framework.Mvc.Helpers;
using HouseHoldBudget.Framework.Security;
using HouseHoldBudget.Framework.Session;

#endregion

namespace HouseHoldBudget.Controllers
{
    [BudgetAuthorize(SuperAdmin = false)]
    public abstract class BudgetControllerBase : Controller
    {
        #region Instance Properties

        /// <summary>
        ///   Gets the current authenticated user.
        /// </summary>
        public BudgetUser CurrentBudgetUser
        {
            get
            {
                return SessionPersister.CurrentBudgetUser;
            }
        }

        /// <summary>
        ///   Gets the serialization helper.
        /// </summary>
        public JsSerializer SerializationHelper
        {
            get
            {
                return new JsSerializer();
            }
        }

        #endregion

        #region Instance Methods

        /// <summary>
        ///   Gets the action.
        /// </summary>
        /// <param name="values"> The values. </param>
        /// <param name="suffix"> The suffix. </param>
        /// <returns> </returns>
        public string GetFormAction(FormCollection values, string suffix = "Button")
        {
            return values.AllKeys.SingleOrDefault(n => n.EndsWith(suffix));
        }

        /// <summary>
        ///   Gets the state of the value in model.
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <returns> </returns>
        public string GetValueInModelState(string key)
        {
            ModelStateDictionary state = ViewData.ModelState;
            if (state.ContainsKey(key))
            {
                if (state[key].Value.AttemptedValue != "undefined")
                {
                    return state[key].Value.AttemptedValue;
                }
            }
            return string.Empty;
        }

        /// <summary>
        ///   Gets the state of the value in model.
        /// </summary>
        /// <typeparam name="T"> </typeparam>
        /// <param name="key"> The key. </param>
        /// <returns> </returns>
        public T GetValueInModelState<T>(string key)
        {
            try
            {
                return (T) Convert.ChangeType(GetValueInModelState(key), typeof (T));
            }
            catch (Exception)
            {
                return default(T);
            }
        }

        /// <summary>
        ///   Display notification
        /// </summary>
        /// <param name="type"> Notification type </param>
        /// <param name="message"> Message </param>
        /// <param name="persistForTheNextRequest"> A value indicating whether a message should be persisted for the next request </param>
        protected virtual void AddNotification(NotifyType type, string message, bool persistForTheNextRequest)
        {
            string dataKey = string.Format("nop.notifications.{0}", type);
            if (persistForTheNextRequest)
            {
                if (TempData[dataKey] == null)
                    TempData[dataKey] = new List<string>();
                ((List<string>) TempData[dataKey]).Add(message);
            }
            else
            {
                if (ViewData[dataKey] == null)
                    ViewData[dataKey] = new List<string>();
                ((List<string>) ViewData[dataKey]).Add(message);
            }
        }

        /// <summary>
        ///   Display error notification
        /// </summary>
        /// <param name="message"> Message </param>
        /// <param name="persistForTheNextRequest"> A value indicating whether a message should be persisted for the next request </param>
        protected virtual void ErrorNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Error, message, persistForTheNextRequest);
        }

        /// <summary>
        ///   Display error notification
        /// </summary>
        /// <param name="exception"> Exception </param>
        /// <param name="persistForTheNextRequest"> A value indicating whether a message should be persisted for the next request </param>
        /// <param name="logException"> A value indicating whether exception should be logged </param>
        protected virtual void ErrorNotification(Exception exception, bool persistForTheNextRequest = true, bool logException = true)
        {
            if (logException)
                LogException(exception);
            AddNotification(NotifyType.Error, exception.Message, persistForTheNextRequest);
        }

        /// <summary>
        ///   Display success notification
        /// </summary>
        /// <param name="message"> Message </param>
        /// <param name="persistForTheNextRequest"> A value indicating whether a message should be persisted for the next request </param>
        protected virtual void SuccessNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Success, message, persistForTheNextRequest);
        }

        /// <summary>
        ///   Called when an unhandled exception occurs in the action.
        /// </summary>
        /// <param name="filterContext"> Information about the current request and action. </param>
        protected override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);
        }

        /// <summary>
        ///   Accesses the denied view.
        /// </summary>
        /// <returns> </returns>
        protected ActionResult AccessDeniedView()
        {
            return RedirectToAction("UnauthorizedAccess", "Account", new {pageUrl = Request.RawUrl});
        }

        /// <summary>
        ///   Contents the result error.
        /// </summary>
        /// <param name="message"> The message. </param>
        /// <returns> </returns>
        protected ContentResult ContentResultError(string message)
        {
            return new ContentResult
                       {
                           Content = String.Format("<span class=\"error\">{0}</span>", message),
                           ContentType = "text/html"
                       };
        }

        /// <summary>
        ///   Contents the result info.
        /// </summary>
        /// <param name="message"> The message. </param>
        /// <returns> </returns>
        protected ContentResult ContentResultInfo(string message)
        {
            return new ContentResult
                       {
                           Content = String.Format("<span class=\"info\">{0}</span>", message),
                           ContentType = "text/html"
                       };
        }

        /// <summary>
        ///   Contents the result success.
        /// </summary>
        /// <param name="message"> The message. </param>
        /// <returns> </returns>
        protected ContentResult ContentResultSuccess(string message)
        {
            return new ContentResult
                       {
                           Content = String.Format("<span class=\"success\">{0}</span>", message),
                           ContentType = "text/html"
                       };
        }

        /// <summary>
        ///   Contents the result warning.
        /// </summary>
        /// <param name="message"> The message. </param>
        /// <returns> </returns>
        protected ContentResult ContentResultWarning(string message)
        {
            return new ContentResult
                       {
                           Content = String.Format("<span class=\"notice\">{0}</span>", message),
                           ContentType = "text/html"
                       };
        }

        /// <summary>
        ///   Log exception
        /// </summary>
        /// <param name="exc"> Exception </param>
        private void LogException(Exception exc)
        {
            //var workContext = EngineContext.Current.Resolve<IWorkContext>();
            //var logger = EngineContext.Current.Resolve<ILogger>();

            //var customer = workContext.CurrentCustomer;
            //logger.Error(exc.Message, exc, customer);
        }

        #endregion
    }
}